package com.zretc.blog.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zretc.api.pojo.blogModule.dtos.BlogDto;
import com.zretc.api.pojo.blogModule.pojos.Blog;
import com.zretc.api.pojo.blogModule.pojos.BlogComment;
import com.zretc.api.pojo.blogModule.pojos.BlogContent;
import com.zretc.blog.mapper.BlogCommentMapper;
import com.zretc.blog.mapper.BlogContentMapper;
import com.zretc.blog.mapper.BlogMapper;
import com.zretc.blog.service.BlogService;
import com.zretc.common.constant.WebConstant;
import com.zretc.common.entity.R;
import com.zretc.common.entity.RespResult;
import com.zretc.minio.service.FileStorageService;
import com.zretc.security.entity.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*;

@Component
@Transactional
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    private BlogContentMapper blogContentMapper;

    @Autowired
    private BlogCommentMapper blogCommentMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public RespResult submit(BlogDto blogDto) {
        if(blogDto == null) {
            return R.fail(405,WebConstant.ERROR_405);
        }
        Blog blog = new Blog();
        BeanUtils.copyProperties(blogDto,blog);
        if(blogDto.getId() == null) {//id不存在，上传博文
            LoginUser loginUser = (LoginUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            blog.setAuthorId(loginUser.getUser().getId());
            blog.setAuthorName(loginUser.getUser().getNick_name());
            blog.setVisible(1);
            blog.setLikes(0);
            blog.setPublishTime(new Date());
            save(blog);
            BlogContent blogContent = new BlogContent();
            blogContent.setBlogId(blog.getId());
            blogContent.setBlogContent(blogDto.getContent());
            blogContent.setImages(blogDto.getImages());
            blogContentMapper.insert(blogContent);
        }else {//id存在，更新博文
            updateById(blog);
            BlogContent blogContent = new BlogContent();
            blogContent.setBlogId(blogDto.getId());
            blogContent.setImages(blogDto.getImages());
            blogContent.setBlogContent(blogDto.getContent());
            blogContentMapper.update(blogContent,Wrappers.<BlogContent>lambdaQuery()
                    .eq(BlogContent::getBlogId,blogDto.getId()));
        }
        return R.success(null);
    }

    @Resource
    private FileStorageService minIOFileStorageService;

    public RespResult uploadImages(MultipartFile[] files){
        ArrayList<String> list = new ArrayList<>();
        for(MultipartFile file : files){
            String fileName = UUID.randomUUID().toString().replace("-", "");
            String originalFilename = file.getOriginalFilename();
            String postfix = originalFilename.substring(originalFilename.lastIndexOf("."));
            try {
                String url = minIOFileStorageService.uploadFile("", fileName + postfix, file.getInputStream(), postfix);
                list.add(url);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        String urls = String.join(",",list);
        return R.success(urls);
    }

    @Override
    public RespResult deleteBlog(BlogDto blogDto) {
        if(blogDto == null) {
            return R.fail(501,"无效参数");
        }
        blogDto.setIsDeleted(1);
        updateById(blogDto);
        BlogContent blogContent = new BlogContent();
        blogContent.setIsDeleted(1);
        blogContentMapper.update(blogContent,Wrappers.<BlogContent>lambdaUpdate().eq(BlogContent::getBlogId,blogDto.getId()));
        List<BlogComment> blogComments = blogCommentMapper.selectList(Wrappers.<BlogComment>lambdaUpdate()
                .eq(BlogComment::getBlogId, blogDto.getId()));
        if(!blogComments.isEmpty()) {
            for (BlogComment blogComment : blogComments) {
                blogComment.setIsDeleted(1);
                blogCommentMapper.updateById(blogComment);
            }
        }
        stringRedisTemplate.delete("blog:likes:" + blogDto.getId());
        return R.success(null);
    }

    @Override
    public RespResult getByChannel(String channel) {
        List<Blog> list = list(Wrappers.<Blog>lambdaQuery()
                .eq(Blog::getChannel, channel)
                .eq(Blog::getIsDeleted,0)
                .eq(Blog::getStatus,1)
                .eq(Blog::getVisible,1));
        return R.success(list);
    }

    @Override
    public RespResult getBlogDetails(BlogDto blogDto) {
        if(blogDto == null) {
            return R.fail(405,WebConstant.ERROR_405);
        }
        HashMap<String,Object> map = new HashMap<>();

        BlogContent blogContent = blogContentMapper.
                selectOne(Wrappers.<BlogContent>lambdaQuery()
                        .eq(BlogContent::getBlogId, blogDto.getId())
                        .eq(BlogContent::getIsDeleted,0));
        if(blogContent != null) {
            blogDto.setContent(blogContent.getBlogContent());
        }else {
            return R.success("博文已删除");
        }
        map.put("blog",blogDto);

        List<BlogComment> commentList =
                blogCommentMapper.selectList(Wrappers.<BlogComment>lambdaQuery()
                        .eq(BlogComment::getBlogId, blogDto.getId())
                        .eq(BlogComment::getIsDeleted,0));
        if(!commentList.isEmpty()) {
            map.put("comments", commentList);
        }else {
            return R.success("博文已删除");
        }
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Boolean like = stringRedisTemplate
                .opsForSet()
                .isMember("blog:likes:" + blogDto.getId(), loginUser.getUser().getId().toString());
        map.put("like",like);
        return R.success(map);
    }
    @Override
    public RespResult createComment(BlogComment toComment,Long blogId,String commentContent) {
        BlogComment newComment = new BlogComment(blogId,commentContent);
        LoginUser loginUser = (LoginUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        newComment.setUserId(loginUser.getUser().getId());
        newComment.setNickName(loginUser.getUser().getNick_name());
        if (toComment != null){//说明将创建的评论是根评论
            if(toComment.getRootId() == null){//说明被评论的是根评论
                newComment.setRootId(toComment.getId());
            }else{
                newComment.setRootId(toComment.getRootId());
            }
            newComment.setToUserId(toComment.getUserId());
            newComment.setToNickName(toComment.getNickName());
        }
        newComment.setCreateTime(new Date());
        blogCommentMapper.insert(newComment);
        return R.success(null);
    }

    @Override
    public RespResult deleteComment(BlogComment blogComment) {
        Long commentId = blogComment.getId();
        if (blogComment.getRootId() == null) {//根评论
            List<BlogComment> blogComments =
                    blogCommentMapper.selectList(Wrappers.<BlogComment>lambdaQuery().eq(BlogComment::getRootId, commentId));
            if (!blogComments.isEmpty()) {
                for (BlogComment comment : blogComments) {
                    comment.setIsDeleted(1);
                    blogCommentMapper.updateById(comment);
                }
            }
        }
        blogComment.setIsDeleted(1);
        blogCommentMapper.updateById(blogComment);
        return R.success(null);
    }

    @Override
    public RespResult like(Long blogId) {
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer userId = loginUser.getUser().getId();
        String key = "blog:likes:" + blogId;
        Boolean liked = stringRedisTemplate.opsForSet().isMember(key, userId.toString());
        if(liked) {//取消点赞
            update().setSql("likes = likes - 1").eq("id",blogId).update();
            stringRedisTemplate.opsForSet().remove(key, userId.toString());
        }else {//发起点赞
            update().setSql("likes = likes + 1").eq("id",blogId).update();
            stringRedisTemplate.opsForSet().add(key, userId.toString());
        }
        return R.success(null);
    }


}
